#include "ball.h"
#include <cmath>
#include <QLine>

Ball::Ball(double Pos_x, double Pos_y, double predkosc_x, double predkosc_y, double promien) {
	this -> center  = QPointF(Pos_x, Pos_y);
	this -> predkosc_x = predkosc_x;
	this -> predkosc_y = predkosc_y;
	this -> promien  = promien;
	this -> masa    = M_PI * promien * promien / 2;
}

Ball::Ball(const Ball& orig) {
	this -> center  = orig.ret_center();
	this -> predkosc_x = orig.ret_predkosc_x();
	this -> predkosc_y = orig.ret_predkosc_y();
	this -> promien  = orig.ret_promien();
}

Ball& Ball::operator=(const Ball& orig) {
	if (&orig == this) return *this;
	this -> center  = orig.ret_center();
	this -> predkosc_x = orig.ret_predkosc_x();
	this -> predkosc_y = orig.ret_predkosc_y();
	this -> promien  = orig.ret_promien();
	return *this;
}

void Ball::move() {
	this -> center.setX(this -> center.x() + this -> predkosc_x);
	this -> center.setY(this -> center.y() + this -> predkosc_y);
	return;
}

void wall_zderzenie(Ball &one)  { // obicie kulki od sciany
	double predkosc_limit = 10; // SPRAWDZIC!!!
	int min_x = 0, min_y = 0, max_x = 800, max_y = 600;// warunki brzegowe (rozmiar pola)
	if ((one.ret_center().x() + one.ret_promien()) > max_x) {
		one.set_pos_x(max_x - one.ret_promien());
		one.set_predkosc_x(-one.ret_predkosc_x());
	}
	else if ((one.ret_center().x() - one.ret_promien()) < min_x) {
		one.set_pos_x(min_x + one.ret_promien());
		one.set_predkosc_x(-one.ret_predkosc_x());
	}
	if ((one.ret_center().y() + one.ret_promien()) > max_y) {
		one.set_pos_y(max_y - one.ret_promien());
		one.set_predkosc_y(-one.ret_predkosc_y());
	}
	else if ((one.ret_center().y() - one.ret_promien()) < min_y) {
		one.set_pos_y(min_y + one.ret_promien());
		one.set_predkosc_y(-one.ret_predkosc_y());
	}
	if (fabs(one.ret_predkosc_x()) > predkosc_limit) { // kiedunke obicia po x
		int sgn = (one.ret_predkosc_x() > 0) ? 1 : -1;
		one.set_predkosc_x(predkosc_limit* sgn);
	}
	if (fabs(one.ret_predkosc_y()) > predkosc_limit) { // kiedunke obicia po y
		int sgn = (one.ret_predkosc_y() > 0) ? 1 : -1;
		one.set_predkosc_y(predkosc_limit* sgn);
	}
}

void ball_zderzenie(Ball &one, Ball &two) { // odbicie kulek od siebie
	double odleglosc = sqrt(pow(one.ret_center().x() - two.ret_center().x(), 2) + pow(one.ret_center().y() - two.ret_center().y(), 2));
	double sum_promien = one.ret_promien() + two.ret_promien();
	if (odleglosc <= sum_promien) {
		double PI = M_PI;

		double dx = one.ret_center().x() - two.ret_center().x(); // odleglosc miedzy promieniami
		double dy = one.ret_center().y() - two.ret_center().y();

		double kat = atan2(dy, dx);

		double mag_1 = sqrt(pow(one.ret_predkosc_x(),2) + pow(one.ret_predkosc_y(),2));
		double mag_2 = sqrt(pow(two.ret_predkosc_x(),2) + pow(two.ret_predkosc_y(),2));

		double kierunek_1 = atan2(one.ret_predkosc_y(), one.ret_predkosc_x());
		double kierunek_2 = atan2(two.ret_predkosc_y(), two.ret_predkosc_x());

		double new_x_predkosc_1 = mag_1 * cos(kierunek_1 - kat); // predkosc 1 kluki po zderzeniu
		double new_y_predkosc_1 = mag_1 * sin(kierunek_1 - kat);

		double new_x_predkosc_2 = mag_2 * cos(kierunek_2 - kat); // predkosc 2 kulki po zderzeniu
		double new_y_predkosc_2 = mag_2 * sin(kierunek_2 - kat);

		double fin_x_predkosc_1 = ((one.ret_masa() - two.ret_masa()) * new_x_predkosc_1 + (two.ret_masa() + two.ret_masa()) * new_x_predkosc_2) / (one.ret_masa() + two.ret_masa());// koncowa predkosc z uwzglednieniem masy 1 kluki
		double fin_x_predkosc_2 = ((one.ret_masa() + one.ret_masa()) * new_x_predkosc_1 + (two.ret_masa() - one.ret_masa()) * new_x_predkosc_2) / (one.ret_masa() + two.ret_masa());

		double fin_y_predkosc_1 = new_y_predkosc_1;
		double fin_y_predkosc_2 = new_y_predkosc_2;

		double one_predkosc_x = cos(kat) * fin_x_predkosc_1 + cos(kat + PI/2) * fin_y_predkosc_1;
		double one_predkosc_y = sin(kat) * fin_x_predkosc_1 + sin(kat + PI/2) * fin_y_predkosc_1;

		double two_predkosc_x = cos(kat) * fin_x_predkosc_2 + cos(kat + PI/2) * fin_y_predkosc_2;
		double two_predkosc_y = sin(kat) * fin_x_predkosc_2 + cos(kat + PI/2) * fin_y_predkosc_2;


		one.set_predkosc_x(one_predkosc_x);
		one.set_predkosc_y(one_predkosc_y);
		two.set_predkosc_x(two_predkosc_x);
		two.set_predkosc_y(two_predkosc_y);
	}
}